package sbc.group1.lab1.alt;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sbc.group1.lab1.common.Car;
import sbc.group1.lab1.common.Logistician;
import sbc.group1.lab1.common.Wheel;
import sun.misc.Signal;
import sun.misc.SignalHandler;

class LogisticianImpl implements Runnable, Logistician {
    public static final Logger log = LoggerFactory.getLogger(LogisticianImpl.class);
    
    
    
    public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException, NumberFormatException, NotBoundException {
        LogisticianImpl logistician= new LogisticianImpl(Integer.parseInt(args[0]));
        final Thread t = new Thread(logistician, "logistician");
        Signal.handle(new Signal("INT"), 
            new SignalHandler() {
                @Override
                public void handle(Signal sig) {
                    t.interrupt();
                }
            });
        
        if (System.getProperty("benchmark") != null && System.getProperty("benchmark").equals("true")) {
            Signal.handle(new Signal("HUP"), 
                    new SignalHandler() {
                        @Override
                        public void handle(Signal sig) {
                            t.start();
                        }
                    });
            System.in.read();
        }else {
            t.start();
            System.in.read();
            t.interrupt();
            t.join();
        }
    }

    private CarService cs;
    private volatile boolean running;
    private final int workerId;
   
    
    public LogisticianImpl(int workerId) throws MalformedURLException, RemoteException, NotBoundException, InterruptedException  {
        cs= (CarService)
                Naming.lookup("rmi://localhost:1099/CarService");
        //cs.init(configFile, spaceURI);
        this.workerId=workerId;
       

    }
    
    @Override
    public int getId() {
        return workerId;
    }
    @Override
    public void run() {
        running=true;
        while(running) {
            try {
                markCar();
                log.info("Marking car as finished succeeded.");
            } catch (InterruptedException e) {
                log.info("Interrupted! Stopping...");
                running=false;
                return;
            }catch (RemoteException e) {
            	log.error("Marking car as finished failed!",e);
                running=false;
                return;
            }
        }
    }
    
    private void markCar() throws InterruptedException, RemoteException {     
        Car car = cs.takeCompleteTestedCar();
        if(car.isDefect()){
        	cs.addDefectCar(car);
        	if(!car.getCarBody().isDefect()){
        		cs.addCarBody(car.getCarBody());
        	}
        	if(!car.getEngine().isDefect()){
        		cs.addEngine(car.getEngine());
        	}
        	for(Wheel w : car.getWheels()){
        		if(!w.isDefect()){
        			cs.addWheel(w);
        		}
        	}
        }
        else {      
	        car.markAsFinished(this);
	        
	        cs.addCar(car);  
        }
    }
    
}
